home *** CD-ROM | disk | FTP | other *** search
/ PsL Monthly 1993 December / PSL Monthly Shareware CD-ROM (December 1993).iso / prgmming / dos / pascal / pcxpas.com / PCXOBJ.ASM < prev    next >
Encoding:
Assembly Source File  |  1990-10-15  |  7.6 KB  |  167 lines

  1. ;============================
  2. ;Linkable module for PCX.PAS
  3. ;============================
  4.  
  5. data    segment word
  6.  
  7.         extrn   datalength: word
  8.         extrn   scratch: dword
  9.         extrn   buff1: word, buff2: word
  10.         extrn   buff1seg, buff2seg: word
  11.         extrn   evenrow: byte
  12.         extrn   is_CGA: byte
  13.         extrn   page_addr: word
  14.         extrn   linestart: word
  15.         extrn   columncount: word
  16.         extrn   plane: word
  17.         extrn   repeatcount: byte
  18.  
  19.         writeproc  dw  (?)
  20.  
  21. data    ends
  22.  
  23. code segment   word public
  24. assume cs:code, ds:data
  25.  
  26.         public  decode_pcx
  27.  
  28.         bytes_per_line equ 80
  29.  
  30. ;===================== Store CGA image in buffer =========================
  31.  
  32. STOREBYTE       PROC    near
  33.  
  34.                 mov     di, linestart       ;get offset of col. 0
  35.                 add     di, dx              ;add column count
  36.                 cmp     evenrow, 0          ;odd or even row?
  37.                 je      row_odd
  38.                 add     di, buff2           ;total offset in even buffer
  39.                 mov     [es:di], bh         ;put byte in even buffer
  40.                 jmp short add_col
  41. row_odd:        add     di, buff1           ;total offset in odd buffer
  42.                 mov     [es:di], bh         ;put byte in odd buffer
  43. add_col:        inc     dx                  ;increment column count
  44.                 cmp     dx, bytes_per_line
  45.                 je      row_ends            ;end of a row
  46.                 ret                         ;not end of row, so finished
  47. row_ends:       xor     dx, dx              ;reset column
  48.                 xor     evenrow, 1          ;evenrow:= not evenrow
  49.                 cmp     evenrow, 1          ;if row is even, start a new line
  50.                 je      noteven
  51.                 mov     es, buff1seg        ;segment of even buffer
  52.                 add     linestart, bytes_per_line   ;new col. 0 offset
  53.                 ret
  54. noteven:        mov     es, buff2seg        ;segment of even buffer
  55.                 ret
  56.  
  57. STOREBYTE  endp
  58.  
  59. ;====================== Write EGA/VGA image to video =====================
  60.  
  61. ;The data in the .PCX file is organized by color plane, by line; that is,
  62. ;all the data for plane 0 for line 1, then for plane 1, line 1, etc.
  63. ;Writing the data to display memory is just a matter of masking out the
  64. ;other planes while one plane is being written to. This is done with the
  65. ;map mask register in the sequencer. All the other weird and wonderful
  66. ;registers in the EGA/VGA do just fine with their default settings, thank
  67. ;goodness.
  68.  
  69. WRITEBYTE proc near
  70.  
  71.                 mov     di, linestart             ;offset of line beginning
  72.                 add     di, dx                    ;add column
  73.                 mov     [es:di], bh               ;put byte in screen buffer
  74.                 inc     dx
  75.                 cmp     dx, bytes_per_line        ;reached end of scanline?
  76.                 je     doneline
  77.                 ret
  78. doneline:       shl     bp, 1                     ;go to next plane
  79.                 cmp     bp, 8                     ;done last plane?
  80.                 jle     setplane                  ;no
  81.                 mov     bp, 1                     ;yes, new line
  82. setplane:       cli                               ;clear interrupts
  83.                 mov     ax, bp                    ;plane is 1, 2, 4, or 8
  84.                 mov     dx, 3C5h                  ;sequencer data register
  85. ;OK to wipe out DX since column counter is being zeroed anyway
  86.                 out     dx, al                    ;mask out 3 planes
  87.                 sti                               ;enable interrupts
  88.                 xor     dx, dx                    ;reset column count
  89.                 cmp     bp, 1                     ;if planes done,
  90.                 je      new_line                  ;   start new line
  91.                 ret
  92. new_line:       add     linestart, bytes_per_line      ;new line
  93.                 ret
  94.  
  95. WRITEBYTE endp
  96.  
  97. ;=========================================================================
  98.  
  99. DECODE_PCX    PROC    NEAR
  100.  
  101.                 push    bp
  102.                 cmp     is_CGA, 1
  103.                 je      CGAonly
  104.                 mov     bp, plane                   ;store plane in bp
  105.                 mov     ax, page_addr               ;start of video buffer
  106.                 mov     es, ax                      ;put in es for addressing
  107.                 mov     writeproc, offset writebyte ;choose EGA/VGA procedure
  108.                 jmp short alltypes
  109. CGAonly:        mov     writeproc, offset storebyte ;choose CGA procedure
  110.                 mov     es, buff1seg                ;segment of odd buffer
  111. alltypes:       mov     bl, repeatcount             ;count in bl
  112.                 mov     si, word ptr 0              ;index into scratch
  113.                 mov     dx, columncount             ;column counter
  114.                 xor     ch, ch                      ;clean up loop counter
  115. ;-------------------------------------------------------------------------
  116. ;Read buffer and decode data
  117.  
  118. ;Here's how the data compression system works. Each byte is either image
  119. ;data or a count byte that tells how often the next image byte is repeated.
  120. ;The byte is image data if it follows a count byte, or if either of the top
  121. ;two bits is clear. Otherwise it is a count byte, with the count derived
  122. ;from the lower 6 bits.
  123.  
  124. getbyte:        cmp     si, datalength              ;end of scratch buffer?
  125.                 je      exit                        ;yes, quit
  126.                 push    es                          ;save video address
  127.                 les     di, scratch                 ;put pointer in es:di
  128.                 add     di, si                      ;add offset
  129.                 mov     bh, [es:di]                 ;get byte from scratch
  130.                 inc     si                          ;increment index
  131.                 pop     es                          ;restore video address
  132.                 cmp     bl, 0                       ;was prev. byte a count?
  133.                 jg      repeats                     ;yes, this is data
  134.                 mov     ah, bh                      ;no, copy byte to ah
  135.                 and     ah, 192                     ; and test high bytes
  136.                 cmp     ah, 192
  137.                 jne     is_data                     ;not set, not a count
  138. ;--------------------------------------------------------------------------
  139. ;It's a count byte
  140.                 xor     bh, 192                     ;get count from 6 low bits
  141.                 mov     bl, bh                      ;store repeat count 
  142.                 jmp short  getbyte                  ;go get data byte
  143. ;----------------------------------------------------------------------------
  144. ;It's a single data byte; call CGA or EGA routine once
  145. is_data:        call    writeproc
  146.                 jmp     getbyte
  147. ;---------------------------------------------------------------------------
  148. ;It's data to be written "count" times; call CGA or EGA routine repeatedly
  149. repeats:        mov     cl, bl                      ;set loop counter
  150. go:             call    writeproc
  151.                 loop    go                          ;write byte cx times
  152.                 mov     bl, 0                       ;clear count byte
  153.                 jmp     getbyte
  154. ;-------------------------------------------------------------------------
  155. exit:           mov     plane, bp                   ;save status for next
  156.                 mov     repeatcount, bl             ;  run thru buffer
  157.                 mov     columncount, dx
  158.                 pop     bp
  159.                 ret
  160.  
  161. DECODE_PCX    endp
  162.  
  163. ;=========================================================================
  164. code ends
  165. end
  166.  
  167.